package com.mmall.concurrence.demo;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 多线程统计素数
 *
 * @author yuelinbo
 * @date 2019/3/19 10:51
 **/
public class CurrentPrimeFinder extends AbstractPrimeFinder {
    //定义线程数量
    private final int poolSize;

    //定义每个线程计算范围内的数字的数量
    private final int numberOfParts;


    public CurrentPrimeFinder(int poolSize, int numberOfParts) {
        this.poolSize = poolSize;
        this.numberOfParts = numberOfParts;
    }

    @Override
    public int countPrimes(int number) {
        int count = 0;
        try {
            final List<Callable<Integer>> partitions = new ArrayList<Callable<Integer>>();
            final int chunksPerPartition = number / numberOfParts;
            for (int i = 0; i < numberOfParts; i++) {
                final int lower = (i * chunksPerPartition) + 1;
                final int upper = (i == numberOfParts - 1) ? number : lower
                        + chunksPerPartition - 1;
                partitions.add(new Callable<Integer>() {
                    public Integer call() {
                        return countPrimesInRange(lower, upper);
                    }
                });
            }
            final ExecutorService executorPool = Executors
                    .newFixedThreadPool(poolSize);
            final List<Future<Integer>> resultFromParts = executorPool
                    .invokeAll(partitions, 10000, TimeUnit.SECONDS);
            executorPool.shutdown();
            for (final Future<Integer> result : resultFromParts)
                count += result.get();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        return count;

    }

    public static void main(String[] args) {
        new CurrentPrimeFinder(4, 50000).timeAndCoumpute(1000000);
    }
}
